/*******************************************************************************
 * Copyright 2011 Towee.net
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package net.towee.server.persistence;

import java.util.List;

import net.towee.model.account.Role;
import net.towee.model.group.GroupData;
import net.towee.model.group.GroupEnterRequest;
import net.towee.model.group.GroupIdentity;
import net.towee.model.group.GroupProfile;
import net.towee.shared.exceptions.NameExistsException;
import net.towee.shared.exceptions.PersistenceException;

/**
 * Interface for the storage and retrieval {@link GroupData)s 
 * @author viiv.c58@gmail.com (Artem Artem'ev)
 */
public interface GroupStore {

	/**
	 * Return group by id
	 * @param id
	 * @return
	 */
	GroupData getGroupById(String id) throws PersistenceException;
	
	/**
	 * Return group with given fields
	 * @param id
	 * @param fields
	 * @return
	 * @throws PersistenceException
	 */
	GroupData getGroupById(String id, String... fields) throws PersistenceException;
	
	/**
	 * Group profile by id
	 * @param id
	 * @return
	 */
	GroupProfile getGroupProfile(String id) throws PersistenceException;
	
	/**
	 * Get group identity by id
	 * @param id
	 * @return
	 * @throws PersistenceException 
	 */
	GroupIdentity getGroupIdentity(String id) throws PersistenceException;
	
	/**
	 * Create new group by group data. Given group MUST have one or more roles
	 * and may have one default role. If this group havn't default role, this
	 * method set first role as default. If group havn't only role, it throw
	 * an exception.
	 * 
	 * @param group
	 * @return TODO
	 * @throws PersistenceException 
	 * @throws NameExistsException 
	 */
	boolean createGroup(GroupData group) throws PersistenceException, NameExistsException;
	
	/**
	 * Update group test quest
	 * @param groupId TODO
	 * @param group
	 * @return TODO
	 */
	boolean updateTestQuest(String groupId, String quest, String answ);
	
	/**
	 * Update profile of group
	 * @param profile
	 * @return TODO
	 */
	boolean updateProfile(GroupProfile profile);
	
	/**
	 * Update print name of group
	 * 
	 * @param identity
	 * @return
	 */
	boolean updatePrintName(String groupId, String printName);
	
	/**
	 * Group searching by Printed name and alias
	 * @param name
	 * @param offset TODO
	 * @param limit TODO
	 */
	List<GroupProfile> findGroup(String name, int offset, int limit);

	/**
	 * Find group by profile
	 * @param profile
	 * @param offset TODO
	 * @param limi TODO
	 * @return
	 */
	List<GroupProfile> findGroupByProfile(GroupProfile profile, int offset, int limi);
	
	/**
	 * Test answer to question of group with given ID
	 * @param groupId
	 * @param answer
	 * @return
	 */
	boolean testGroupAnswer(String groupId, String answer);
	
	/**
	 * Update existing role
	 * @param role
	 */
	boolean updateRole(Role role);
	
	/**
	 * Create new role
	 * @param role
	 */
	void createRole(Role role);
	
	/**
	 * Return role with given id and group
	 * @param roleId
	 * @param groupId
	 * @return
	 */
	Role getRole(String roleId, String groupId);
	
	/**
	 * Remove group with id
	 * @param id
	 * @throws PersistenceException 
	 */
	void removeGroup(String id) throws PersistenceException;
	
	/**
	 * Add new role to group. Given role MUST NOT be created before.
	 * This method create it itself.
	 * 
	 * @param groupId
	 * @param role
	 * @return TODO
	 */
	boolean addRole(String groupId, Role role);
	
	/**
	 * Remove role from group
	 * @param groupId
	 * @param role
	 * @return
	 * @throws PersistenceException 
	 */
	boolean removeRole(String groupId, Role role) throws PersistenceException;
	
	/**
	 * Set default role to group
	 * @param groupId
	 * @param role
	 * @return
	 */
	boolean setDefaultRole(String groupId, Role role);
	
	/**
	 * Get enter requests of given group
	 * 
	 * @param groupId
	 * @param offset
	 * @param limit
	 * @return
	 */
	List<GroupEnterRequest> getEnterRequests(String groupId, int offset, int limit);
	
	/**
	 * Add new enter request. If request with given account already exists it do
	 * nothing and return false.
	 * 
	 * @param groupId
	 * @param request
	 * @return
	 */
	boolean addEnterRequest(String groupId, GroupEnterRequest request);
	
	/**
	 * This method process enter request.
	 * If request with given accountId exists it remove request from list,
	 * enter account to given group and return true. Otherwise it return false.
	 * 
	 * @param groupId
	 * @param account
	 * @return
	 * @throws PersistenceException 
	 */
	boolean processEnterRequest(String groupId, String accountId) throws PersistenceException;
	
	/**
	 * Get groups by given list of ids
	 * 
	 * @param ids
	 * @return
	 */
	List<GroupProfile> getGroupsByIds(Iterable<String> ids);

	/**
	 * If administrator of given group don't want add given
	 * account to group, he remove it by this method.
	 * 
	 * @param groupId
	 * @param accountId
	 * @return
	 */
	boolean removeEnterRequest(String groupId, String accountId);

	/**
	 * Return list of all groups sorted by number of users
	 * @param offset
	 * @param limit
	 * @return
	 */
	List<GroupProfile> getAllGroups(int offset, int limit);
}
